package com.burnerpat.fl2d.core.entity;

import com.burnerpat.fl2d.core.shape.*;
import com.burnerpat.fl2d.math.FastMath;
import com.burnerpat.fl2d.math.Vector2D;

public class PhysicalEntity extends Entity
{
	private Shape shape = null;
	
	public PhysicalEntity(long pId, Vector2D position, double alpha, Shape pShape)
	{
		super(pId, position, alpha);
		shape = pShape;
	}
	
	public PhysicalEntity()
	{
		super();
	}
	
	public Shape getShape()
	{
		return shape;
	}
	
	public void setShape(Shape pShape)
	{
		shape = pShape;
	}
	
	public boolean intersects(PhysicalEntity other)
	{
		if (shape == null || other.getShape() == null)
		{
			return false;
		}
		
		if (!aabbIntersection(other))
		{
			return false;
		}
		
		Shape s1 = shape;
		Shape s2 = other.getShape();
		
		if ((s1 instanceof Dot) || (s2 instanceof Dot))
		{
			return true;
		}
		else if (s1 instanceof Rectangle)
		{
			if ((s2 instanceof Dot) || (s2 instanceof Rectangle))
			{
				return true;
			}
			else if (s2 instanceof Disc)
			{
				//TODO: implement Disc <-> Rectangle intersection check
				return true;
			}
			
			return true;
		}
		else if (s1 instanceof Disc)
		{
			if (s2 instanceof Dot)
			{
				Disc d1 = (Disc)s1;
				return (super.getPosition().delta(other.getPosition()).sqrLength() < d1.getRadius());
			}
			else if (s2 instanceof Rectangle)
			{
				//TODO: implement Disc <-> Rectangle intersection check
				return true;
			}
			else if (s2 instanceof Disc)
			{
				return discIntersection(other);
			}
			
			return true;
		}
		else
		{
			return true;
		}
	}
	
	public boolean aabbIntersection(PhysicalEntity other)
	{
		Rectangle r1 = shape.getAABB();
		Rectangle r2 = other.getShape().getAABB();
		
		Vector2D delta = super.getPosition().delta(other.getPosition());
		
		delta = delta.sub(r1.toVector2D().add(r2.toVector2D()).mul(0.5));
		
		return (delta.x < 0.0 || delta.y < 0.0);
	}
	
	public boolean discIntersection(PhysicalEntity other)
	{		
		try
		{
			Disc d1 = (Disc)shape;
			Disc d2 = (Disc)other.getShape();
			
			Vector2D delta = super.getPosition().delta(other.getPosition());
			
			double r2 = FastMath.sqr(d1.getRadius() + d2.getRadius());
			
			return (delta.sqrLength() < r2);
		}
		catch (ClassCastException ex)
		{
			return false;
		}			
	}
}
